package com.osfw.dbadminer.controller.manager;

import com.osfw.dbadminer.domain.database.SqlExecuteParam;
import com.osfw.dbadminer.domain.database.SqlExecuteResult;
import com.osfw.dbadminer.entity.operlog.DbaOperLog;
import com.osfw.dbadminer.enums.DbOperType;
import com.osfw.dbadminer.service.operlog.IDbaOperLogService;
import com.osfw.dbadminer.util.SQLParserUtils;
import com.osfw.framework.constants.Constants;
import com.osfw.framework.manager.AsyncFactory;
import com.osfw.framework.utils.AddressUtils;
import com.osfw.framework.utils.IpUtils;
import com.osfw.framework.utils.ServletUtils;
import com.osfw.framework.utils.spring.SpringUtils;
import com.osfw.system.entity.manage.SysUser;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimerTask;

public class DbaAsyncFactory extends AsyncFactory {

    /**
     * 数据库操作日志记录
     *
     * @param param   sql执行参数
     * @param results sql执行结果
     * @param sysUser 操作用户
     */
    public static TimerTask recordExecStmtOper(final SqlExecuteParam param, final List<SqlExecuteResult> results, final SysUser sysUser) {
        return new TimerTask() {
            @Override
            public void run() {
                List<DbaOperLog> logs = new ArrayList<>();
                if (param != null && results != null && !results.isEmpty()) {
                    results.stream().forEach(result -> {
                        DbaOperLog operLog = new DbaOperLog();
                        if (param.getOperLogId() == null) {
                            // 当无审批时的赋值
                            operLog.setConnectId(param.getConnectId());
                            operLog.setConnectName(param.getConnectName());
                            operLog.setDatabaseName(param.getDatabaseName());
                            operLog.setDatatableName(param.getDatatableName());
                            operLog.setOperType(SQLParserUtils.getDbOperType(result.getStmt()).getType());
                            operLog.setOperUserId(sysUser.getUserId());
                            operLog.setOperUserName(sysUser.getUserName());
                            operLog.setOperDeptId(sysUser.getDeptId());
                            operLog.setOperDeptName(sysUser.getDeptName());
                            operLog.setOperIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                            operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
                            operLog.setOperTime(new Date()); //当无审批流程时，操作时间和执行时间一致
                            operLog.setIsApproval(0);
                            operLog.setActProcinstId(null);
                            operLog.setExecStmt(result.getStmt());
                            operLog.setExecResult(result.getMsg());
                            operLog.setExecStatus(result.isError() || result.isWarn() ? Constants.YES_INTEGER : Constants.NO_INTEGER);
                            operLog.setExecTime(new Date());
                            operLog.setCostTime(result.getTimes());
                        } else {
                            // 当无审批时的赋值
                            operLog.setOperId(param.getOperLogId());
                            operLog.setExecResult(result.getMsg());
                            operLog.setExecStatus(result.isError() || result.isWarn() ? Constants.YES_INTEGER : Constants.NO_INTEGER);
                            operLog.setExecTime(new Date());
                            operLog.setCostTime(result.getTimes());
                        }
                        logs.add(operLog);
                    });
                }
                if (!logs.isEmpty()) {
                    SpringUtils.getBean(IDbaOperLogService.class).saveOrUpdateBatch(logs);
                }
            }
        };
    }

    /**
     * 数据库操作日志记录
     *
     * @param param    sql执行参数
     * @param result   sql执行结果
     * @param operType sql操作类型
     * @param sysUser  操作用户
     */
    public static TimerTask recordImportOrExportOper(final SqlExecuteParam param, final SqlExecuteResult result, final DbOperType operType, final SysUser sysUser) {
        return new TimerTask() {
            @Override
            public void run() {
                if (param != null && result != null) {
                    DbaOperLog operLog = new DbaOperLog();
                    if (param.getOperLogId() == null) {
                        // 当无审批时的赋值
                        operLog.setConnectId(param.getConnectId());
                        operLog.setConnectName(param.getConnectName());
                        operLog.setDatabaseName(param.getDatabaseName());
                        operLog.setDatatableName(param.getDatatableName());
                        operLog.setOperType(operType.getType());
                        operLog.setOperUserId(sysUser.getUserId());
                        operLog.setOperUserName(sysUser.getUserName());
                        operLog.setOperDeptId(sysUser.getDeptId());
                        operLog.setOperDeptName(sysUser.getDeptName());
                        operLog.setOperIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                        operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
                        operLog.setOperTime(new Date()); //当无审批流程时，操作时间和执行时间一致
                        operLog.setIsApproval(0);
                        operLog.setActProcinstId(null);
                        operLog.setExecStmt(result.getStmt());
                        operLog.setExecResult(result.getMsg());
                        operLog.setExecStatus(result.isError() || result.isWarn() ? Constants.YES_INTEGER : Constants.NO_INTEGER);
                        operLog.setExecTime(new Date());
                        operLog.setCostTime(result.getTimes());
                    } else {
                        // 当无审批时的赋值
                        operLog.setOperId(param.getOperLogId());
                        operLog.setExecResult(result.getMsg());
                        operLog.setExecStatus(result.isError() || result.isWarn() ? Constants.YES_INTEGER : Constants.NO_INTEGER);
                        operLog.setExecTime(new Date());
                        operLog.setCostTime(result.getTimes());
                    }
                    if (operLog != null) {
                        SpringUtils.getBean(IDbaOperLogService.class).saveOrUpdate(operLog);
                    }
                }

            }
        };
    }

}
